package com.example.leetdemo.test;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class InvestmentReturnCalculator {


    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        BigDecimal guess = new BigDecimal("-333.25");
        List<BigDecimal> cf = new ArrayList<>();
        cf.add(guess);
        cf.add(new BigDecimal("65.53"));
        cf.add(new BigDecimal("63.84"));
        cf.add(new BigDecimal("55.49"));
        cf.add(new BigDecimal("53.80"));
        cf.add(new BigDecimal("52.11"));
        cf.add(new BigDecimal("50.42"));
        cf.add(new BigDecimal("48.73"));
        cf.add(new BigDecimal("47.05"));
        cf.add(new BigDecimal("45.36"));
        cf.add(new BigDecimal("76.99"));
        cf.forEach(c -> list.add(c.toString()));
        int loanTerm = 10;
        System.err.println(calculator(cf, loanTerm));
    }
        /**
         * 计算综合年利率
         * 	计算公式 irr * loanTerm * 100 【100代表100%】
         * @param list 【第一个元素为本金的负数，后面为每期应还金额（本金+利息）】
         * @param loanTerm
         * @return
         */
        public static String calaulate(List<BigDecimal> list, int loanTerm) {
            /**	计算公式 irr * 期数 * 100 【100代表100%】*/
            double irr = new BigDecimal(calculator(list, loanTerm)).multiply(new BigDecimal(loanTerm)).multiply(new BigDecimal("100")).doubleValue();
            DecimalFormat df = new DecimalFormat("0.00");
            return df.format(Math.abs(irr));
        }

        private static double NPV(double r, List<BigDecimal> netCash) {

            double npv = 0;

            if (netCash.size() != 0) {
                for (int count = 0; count < netCash.size(); count++) {
                    npv += netCash.get(count).doubleValue() / Math.pow(1 + r, count);
                }
                return npv;
            }
            return Double.NaN;
        }

        /**
         * IRR函数
         * @author: wgc
         * @date: 2021年4月30日 下午5:04:50
         * @param netCashArr
         * @param interval
         * @return
         */
        private static double calculator(List<BigDecimal> netCashArr, int interval) {

            double MINDIF = 0.001;

            int LOOPNUM = 2000;

            double irr = 0;
            double r1 = new BigDecimal("0.1").doubleValue();
            double r2 = new BigDecimal("0.09").doubleValue();
            double npv1 = NPV(r1, netCashArr);
            double npv2 = NPV(r2, netCashArr);
            int count = 0;
            while (Math.abs(npv2) > MINDIF && count < LOOPNUM) {
                irr = r2 - npv2 * (r2 - r1) / (npv2 - npv1);
                r1 = r2;
                r2 = irr;
                npv1 = npv2;
                npv2 = NPV(r2, netCashArr);
                count++;
            }
            if (Math.abs(npv2) < MINDIF && count <= LOOPNUM)
                return irr;
            else
                return Double.NaN;
        }

    }
